package com.dp.singleton;

/**
 * <p>Title: 双重检验锁DCL</p>
 * <p>Description:
 * <p>
 * 编写的是多线程程序，则不要删除代码中的关键字 volatile 和 synchronized，否则将存在线程非安全的问题。
 * 如果不删除这两个关键字就能保证线程安全，但是每次访问时都要同步，会影响性能，且消耗更多的资源，这是懒汉式单例的缺点。
 * </p>
 * <p>Copyright: Copyright (c) 2018</p>
 * <p>Company: 764198025@qq.com</p>
 *
 * @author wangyl
 * @version 1.0
 * @date 2020/6/30
 */
public class DclSingleton {

    /****
     * volatile 保证 instance 在所有线程中同步
     */
    private static volatile DclSingleton instance = null;

    /***
     * private 避免类在外部被实例化
     */
    private DclSingleton() {}

    /***
     * 双重锁定检查
     * @return 单例对象
     */
    public static DclSingleton getInstance() {
        if (null == instance) {
            synchronized (DclSingleton.class) {
                if (null == instance) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    instance = new DclSingleton();
                }
            }
        }
        return instance;
    }

    /****
     * 模拟多线程下并发测试
     * @param ags
     */
    public static void main(String[] ags){
        long start = System.currentTimeMillis();
        for (int i = 0; i < 1000; i++) {
            new Thread(new Runnable() {
                public void run() {
                    DclSingleton lazySingleton03 = DclSingleton.getInstance();
                    System.out.println(Thread.currentThread().getName() + lazySingleton03);
                }
            }).start();
        }
        long end = System.currentTimeMillis();
        System.out.println("总耗时：" + (end - start));
    }
}
